package com.cskaoyan.service;

import com.cskaoyan.bean.bo.TopicBatchDeleteBo;
import com.cskaoyan.bean.bo.TopicCreateBo;
import com.cskaoyan.bean.bo.TopicDeleteBo;
import com.cskaoyan.bean.bo.TopicUpdateBo;
import com.cskaoyan.bean.param.BaseParam;
import com.cskaoyan.bean.po.TopicCreatePo;
import com.cskaoyan.bean.po.TopicPo;
import com.cskaoyan.bean.po.TopicReadTopicPo;
import com.cskaoyan.bean.po.TopicUpdatePo;
import com.cskaoyan.bean.vo.*;
import com.cskaoyan.mapper.TopicMapper;
import com.cskaoyan.util.StringToArrayUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;

/**
 * @author: 陈慧颖
 * @time: Created by chy on 2022/6/4 23:05
 */
@Service
public class TopicServiceImpl implements TopicService {
    @Autowired
    TopicMapper topicMapper;

    public List<TopicVo> listAll(BaseParam baseParam,String title,String subtitle) {
        // queryAll 查询后返回的 goods 是 String ; 直接使用 TopicPo 接收
        /**
         * 若直接使用 Vo 接收, 无法做转换 ;
         * 或:  Vo 接收, 将 Vo 的 goods 成员修改后返回  ;   还是要新建一个类;
         */
        List<TopicPo> topicPoList = topicMapper.queryAll(baseParam,title,subtitle);
        //
        ArrayList<TopicVo> topicVos = new ArrayList<>();
        // Po->Vo
        for (int i = 0; i < topicPoList.size(); i++) {
            TopicPo  temp =   topicPoList.get(i);
            TopicVo topicVo = new TopicVo();
            topicVo.setId(temp.getId());
            topicVo.setTitle(temp.getTitle());
            topicVo.setSubtitle(temp.getSubtitle());
            topicVo.setPrice(temp.getPrice());
            topicVo.setReadCount(temp.getReadCount());
            topicVo.setPicUrl(temp.getPicUrl());
            topicVo.setSortOrder(temp.getSortOrder());

            // 将 Po 的 goods 转化为 list; 给到 Vo;
            String goods = temp.getGoods();
            List<Integer> integers = StringToArrayUtils.toArray(goods);
            topicVo.setGoods(integers);
            topicVo.setAddTime(temp.getAddTime());
            topicVo.setUpdateTime(temp.getUpdateTime());
            topicVo.setDeleted(temp.getDeleted());
            topicVo.setContent(temp.getContent());


            topicVos.add(topicVo);
        }

        return topicVos;

    }

    /**
     * BeanUtil 工具类
     * 使用 typeHandler 定义;
     * 引入反射工具类;用来赋值;
     */
    public TopicCreateVo create(TopicCreateBo topicCreateBo) {

        // 1. 先使用传统方式;              思考: topicCreateBo 如何被typeHandler处理为Po;? VXCollectAddOrDeleteBo --> Po
        TopicCreatePo topicCreatePo = new TopicCreatePo();
        topicCreatePo.setContent(topicCreateBo.getContent());
        // 客户端传入[];  Po 接收为 String;
        topicCreatePo.setGoods(topicCreateBo.getGoods().toString());
        topicCreatePo.setPrice(topicCreateBo.getPrice());
        topicCreatePo.setSubtitle(topicCreateBo.getSubtitle());
        topicCreatePo.setTitle(topicCreateBo.getTitle());
        // Po 需要的 addTime , updateTime; 由 java 中 newDate()实现;
        topicCreatePo.setAddTime(new Date()); // VXCollectAddOrDeleteBo 没有提供;
        topicCreatePo.setUpdateTime(new Date());
        topicCreatePo.setDeleted(false);// 默认是 0 ; 在 java 代码里写 false ; 在 sql 里写 true;
        // 2. sql 查询
        int count = topicMapper.createOneTopic(topicCreatePo);
        // 3. 将 TopCreateBo 参数给到  TopicCreateVo ;  VXCollectAddOrDeleteBo-->Vo;
        TopicCreateVo topicCreateVo = new TopicCreateVo();
        topicCreateVo.setAddTime(topicCreatePo.getAddTime());
        topicCreateVo.setContent(topicCreatePo.getContent());
        // 应由 typehandler 处理;
        List<Integer> integers = StringToArrayUtils.toArray(topicCreatePo.getGoods());
        topicCreateVo.setGoods(integers);
        // 这是id 是由数据库管理的 auto_increment;  必须配合 useGeneratedKeys;  keyProperty;
        topicCreateVo.setId(topicCreatePo.getId());
        // 对于 price; 回显使用 Integer ; 客户端传来使用 String; 数据库使用decimal;
        // topicCreateVo.setPrice(Integer.parseInt(topicCreatePo.getPrice()));
        topicCreateVo.setPrice(topicCreatePo.getPrice());
        topicCreateVo.setSubtitle(topicCreatePo.getSubtitle());
        topicCreateVo.setTitle(topicCreatePo.getTitle());
        topicCreateVo.setUpdateTime(topicCreatePo.getUpdateTime());
        return topicCreateVo;

    }

    /**
     * 该方法删除一个 topic 信息;
     *
     * @param topicDeleteBo
     */
    // public void deleteOne(TopicDeleteBo topicDeleteBo) {
    //     int count = topicMapper.delete(topicDeleteBo);
    // }

    /**
     * 假删除 delete;
     * @param topicDeleteBo
     */
    public void deleteOne(TopicDeleteBo topicDeleteBo) {
        int count = topicMapper.delete(topicDeleteBo);
    }


    /**
     * 核心逻辑,处理/admin/topic/update 接口
     *
     * @param topicUpdateBo
     * @return
     */
    @Override
    public TopicUpdateVo updateOneTopic(TopicUpdateBo topicUpdateBo) {
        // VXCollectAddOrDeleteBo->po ; 复用 topicUpdateBo 对象;  因为 po 和 bo 一模一样;

        TopicUpdatePo topicUpdatePo = new TopicUpdatePo();
        topicUpdatePo.setAddTime(topicUpdateBo.getAddTime());
        topicUpdatePo.setContent(topicUpdateBo.getContent());
        topicUpdatePo.setDeleted(topicUpdateBo.getDeleted());
        // topicUpdatePo.setGoods(topicUpdateBo.getGoods().toString()); // 客户端传递 [];
        // List<Integer> integers = StringToArrayUtils.toArray();
        System.out.println(topicUpdateBo == null); // false;
        System.out.println(topicUpdateBo.getGoods());// 如果 bo 不传入, 就会NPE;
        System.out.println(topicUpdateBo.getGoods().toString());
        topicUpdatePo.setGoods(topicUpdateBo.getGoods().toString()); // 客户端传递"[]"
        topicUpdatePo.setId(topicUpdateBo.getId());
        topicUpdatePo.setPicUrl(topicUpdateBo.getPicUrl());
        topicUpdatePo.setPrice(topicUpdateBo.getPrice());
        topicUpdatePo.setReadCount(topicUpdateBo.getReadCount());
        topicUpdatePo.setSortOrder(topicUpdateBo.getSortOrder());
        topicUpdatePo.setSubtitle(topicUpdateBo.getSubtitle());
        topicUpdatePo.setTitle(topicUpdateBo.getTitle());
        // Po 需要使用 java 代码`new Date()`将 updateTime设定为操作时的时间 , 而不是从客户端获取到的 updateTime; 那是上一次的;
        topicUpdatePo.setUpdateTime(new Date());
        // sql
        int count = topicMapper.updateOneTopic(topicUpdatePo);
        // po/bo -->Vo;
        /**
         * 不可以复用 VXCollectAddOrDeleteBo 给 VO; VXCollectAddOrDeleteBo 需要更新被修改的值才可以充当 Vo;
         */
        TopicUpdateVo topicUpdateVo = new TopicUpdateVo();
        topicUpdateVo.setAddTime(topicUpdateBo.getAddTime());
        topicUpdateVo.setContent(topicUpdateBo.getContent());
        System.out.println(topicUpdateBo==null);// false;
        System.out.println(topicUpdateBo.getDeleted()); //false;
        topicUpdateVo.setDeleted(topicUpdateBo.getDeleted());// 报 NPE
        topicUpdateVo.setGoods(topicUpdateBo.getGoods());
        topicUpdateVo.setId(topicUpdateBo.getId());
        topicUpdateVo.setPicUrl(topicUpdateBo.getPicUrl());
        topicUpdateVo.setPrice(topicUpdateBo.getPrice());
        topicUpdateVo.setReadCount(topicUpdateBo.getReadCount());
        System.out.println(topicUpdateBo==null); // false;
        System.out.println(topicUpdateBo.getSortOrder());// null
        topicUpdateVo.setSortOrder(topicUpdateBo.getSortOrder());// 会报 NPE
        topicUpdateVo.setSubtitle(topicUpdateBo.getSubtitle());
        topicUpdateVo.setTitle(topicUpdateBo.getTitle());
        topicUpdateVo.setUpdateTime(topicUpdatePo.getUpdateTime());// 其实使用 VXCollectAddOrDeleteBo 或 Po  关键是 updateTime 不同;其余都可以 ;
        // 给topicUpdateVo赋值;并返回;

        return topicUpdateVo;


    }

    /**
     * 核心逻辑: 处理/admin/topic/read 接口;
     *
     * @param id 是 market_topic表的 id
     *           而 market_topic表的 goods 列表 存着 goodsId;
     *           <p>
     *           404 一定是 请求参数获取的问题;
     * @return
     */
    @Override
    public TopicReadVo read(Integer id) {
        TopicReadVo topicReadVo = new TopicReadVo();
        // 1. 查询 market_topic 表;
        /**
         * 必须要求 readByTopicId返回的对象的 goods 类型是 list; 若不是则转化;
         */

        TopicReadTopicPo topicReadTopicPo  =      topicMapper.readByTopicId(id);
        TopicReadTopicVo topicReadTopicVo =  new TopicReadTopicVo();
        // 多个转化;
        topicReadTopicVo.setId(topicReadTopicPo.getId());
        topicReadTopicVo.setTitle(topicReadTopicPo.getTitle());
        topicReadTopicVo.setSubtitle(topicReadTopicPo.getSubtitle());
        topicReadTopicVo.setPrice(topicReadTopicPo.getPrice());
        topicReadTopicVo.setReadCount(topicReadTopicPo.getReadCount());
        topicReadTopicVo.setPicUrl(topicReadTopicPo.getPicUrl());
        topicReadTopicVo.setSortOrder(topicReadTopicPo.getSortOrder());
        List<Integer> integers = StringToArrayUtils.toArray(topicReadTopicPo.getGoods());
        topicReadTopicVo.setGoods(integers);
        topicReadTopicVo.setAddTime(topicReadTopicPo.getAddTime());
        topicReadTopicVo.setUpdateTime(topicReadTopicPo.getUpdateTime());
        topicReadTopicVo.setDeleted(topicReadTopicPo.getDeleted());
        topicReadTopicVo.setContent(topicReadTopicPo.getContent());


                // 2. 从 1 获取到 goodsId;
        List<Integer> goodsIdList =StringToArrayUtils.toArray(topicReadTopicPo.getGoods());

        // 3. 查询 market_goods 表;
        // 4. 将根据不同的 goodsId 查询出来的topicReadGoodsVo放入一个容器里;
        List<TopicReadGoodsVo> linkedList = new LinkedList();
        for (Integer goodsId : goodsIdList) {
            // 线程不安全;
            TopicReadGoodsVo topicReadGoodsVo = topicMapper.readByGoodsId(goodsId);
            linkedList.add(topicReadGoodsVo);
        }
        // 5. 为topicReadVo设置成员;
        topicReadVo.setGoodsList(linkedList);
        topicReadVo.setTopic(topicReadTopicVo);


        return topicReadVo;

    }

    /**
     * 本方法 read1 为备份方法,可以忽略不看; chy;
     * 本方法 无法生效; 已被否定;
     * 2022年06月05日20:24:54
     *
     * @param id
     * @return
     */
    public TopicReadVo read1(Integer id) {
        TopicReadVo topicReadVo = new TopicReadVo();
        // 如何在 sql 语句里 做到将 形如 varchar :  "[1,2,4]"  -->  int :2   进行连表查询?
        return topicReadVo;

    }

    /**
     *  批量删除数据;
     * @param topicBatchDeleteBo
     */
    public void batchDelete(TopicBatchDeleteBo topicBatchDeleteBo) {
        // int count  =  topicMapper.batchDelete(topicBatchDeleteBo);
        Integer[] ids = topicBatchDeleteBo.getIds();
        for (Integer id : ids) {
            TopicDeleteBo topicDeleteBo = new TopicDeleteBo();
            topicDeleteBo.setId(id);
            this.deleteOne(topicDeleteBo);
        }

    }
}
